/*
 * Copyright (c) 2009
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.dcarew.hudson;

import java.util.ArrayList;
import java.util.List;

import org.dcarew.hudson.utils.NotificationUtils;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.swt.widgets.Display;

/**
 * Updates the Hudson status three times a minute.
 * 
 * @author Devon Carew
 */
public class HudsonUpdateJob
	extends Job
{
	/* 30 second delay between updates */
	private static final int 		UPDATE_DELAY = 30 * 1000;
	
	private static HudsonUpdateJob 	updateJob;
	
	private List oldFailed = new ArrayList();
	
	
	public HudsonUpdateJob()
	{
		super("Hudson Status Update");
		
		setUser(false);
		setSystem(true);
		setPriority(Job.LONG);
		
		updateJob = this;
	}
	
	public static void refresh()
	{
		if (updateJob != null)
		{
			updateJob.cancel();
			updateJob.schedule();
		}			
	}
	
	protected IStatus run(IProgressMonitor monitor)
	{
		if (HudsonPlugin.getPlugin() == null || HudsonPlugin.getPlugin().getPreferenceStore() == null)
		{
			schedule(2 * 1000);
		}
		else
		{
			updateHudsonStatus();
			
			schedule(UPDATE_DELAY);
		}
		
		return Status.OK_STATUS;
	}
	
	private void updateHudsonStatus()
	{
		HudsonCommunications communications = new HudsonCommunications();
		
		communications.initFromPreferences();
		
		if (HudsonStartup.getStartup() == null)
			return;
		
		if (communications.getBaseURL() == null || communications.getBaseURL().length() == 0)
		{
			HudsonStartup.getStartup().update(
				true, 
				false,
				"No Hudson server specified.",
				null,
				null,
				null);
		}
		else if (communications.updateStatus())
		{
			HudsonStartup.getStartup().update(
				!communications.getHasFailedprojects(),
				communications.getHasRunningProjects(),
				communications.getSummary(),
				communications.getDescription(),
				communications.getView(),
				communications.getViews());
			
			diffFailedProjects(communications.getFailedProjects());
		}
		else
		{
			HudsonStartup.getStartup().updateError(
				communications.getSummary(), communications.getDescription());
		}
	}

	private void diffFailedProjects(List currentFailed)
	{
		final List newFailed = new ArrayList();
		
		for (int i = 0; i < currentFailed.size(); i++)
		{
			String project = (String)currentFailed.get(i);
			
			if (!oldFailed.contains(project))
				newFailed.add(project);
		}
		
		oldFailed = currentFailed;
		
		if (newFailed.size() > 0)
		{
			Display.getDefault().asyncExec(new Runnable() {
				public void run() {
					notifyFailed(newFailed);
				}
			});
		}
	}
	
	private void notifyFailed(List newFailed)
	{
		if (HudsonPlugin.getDontNotify())
			return;
		
		StringBuffer message = new StringBuffer();
		
		if (newFailed.size() == 1)
		{
			message.append(newFailed.get(0) + " build failed.");
		}
		else
		{
			for (int i = 0; i < newFailed.size(); i++)
			{
				if (i > 0)
					message.append(", ");
				
				message.append(newFailed.get(i));
			}
			
			message.append(" builds failed.");
		}
		
		NotificationUtils.notify(
			HudsonPlugin.getImage("resources/icons/hudson.gif"),
			"Hudson Build Failure",
			message.toString());
	}
	
}
